#!/usr/bin/python
# -*- coding:utf-8 -*-

import pca2
from PIL import Image
import numpy
from numpy import *
import pylab
from random import randint
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib
from matplotlib import *
from config import Config
from algknn import algKNN

def elegido():
	conf = Config()
	return (randint(1,conf.tambd) % 2) == 0


def carga( ruta, rango ):
	imlist = list()
	a, b = rango
	for k in range(a,b) :
		img_file = '%s/img%03d.pgm' % (ruta,k)
		imlist.append(img_file)

	return imlist

def arrayor(arrA, arrB):
	aux = list()

	for a,b in zip(arrA, arrB):
		item = 1 if a | b else 0
		aux.append(item)
	
	res = sum(aux) / float(len(aux)) * 100
	return res

	

def creaMatriz(carpetas):
	randir = 0
	conf = Config()
	ini, mit, fin = 1, conf.imgent + 1, conf.imagenes + 1
	list_total = list()
	pruebas    = list()
	entrena    = list()

	for k in carpetas:
		if randir < conf.dirent and elegido():
			imlist_test = carga( 'img%d' % k, (ini, mit) )
			imlist      = carga( 'img%d' % k, (mit, fin) )
   			randir += 1
   			pruebas.append(k)
		else:
			imlist_test = []
			imlist      = carga( 'img%d' % k, (ini, fin) )
			entrena.append(k)
	

		list_total += imlist + imlist_test
	
	return list_total, pruebas, entrena

def muestraimg(img, titulo):
	pylab.figure()
	pylab.title(titulo)
	pylab.gray()
	pylab.imshow(img)
	
	
def errorCuadratico(S):
	print S
	print type(S)

	conf = Config()
	dist = [ k / (conf.tambd+5.0) for k in range(conf.tambd+6) ]
	tam = conf.tambd + 1
	emc = [None]*tam
	porcentaje = [None]*tam
	EOpt = [None]*tam
	
	print len(S)
	print EOpt
	print len(EOpt)

	for q in range(conf.tambd):
		emc[q+1]=sum(S[q+1:])
		porcentaje[q+1]=sum(S[1:q])/sum(S[1:])
	

		# Porcentaje de perdida de la varianza presente en el 
		#vector de caracteristicas original
		EOpt[q+1]=sqrt(((dist[q+1])*(dist[q+1]))+
				((1-porcentaje[q+1])*(1-porcentaje[q+1])))
	#termina error cuadratico
	print 80 * '-'
	print EOpt

	
	a=min(EOpt[1:])
	print "el mejor valor optimo es"
	print a

	vpmin = EOpt.index(min(EOpt[1:]))
	print "y se encuentra empleando los vectores propios"
	print vpmin

	nu = porcentaje[vpmin]
	print "el nu es"
	print nu

	return a, vpmin, nu, porcentaje


	
def main():
	conf = Config()
	conf.configura('refac.conf')
	
	vfaces, pruebas, entrena = creaMatriz( range(1,conf.personas + 1) )

	im = numpy.array(Image.open(vfaces[0])) 

	m,n = im.shape
	print '(m,n) =', m,n
	
	imnbr = len(vfaces) 
	
	immatrix = numpy.array(
			[numpy.array(Image.open(vfaces[i])).flatten() 
				for i in range(imnbr)],'f')
	
	V,S,immean,EV = pca2.pca(immatrix)

	print '(m,n) =', m,n
	immean = immean.reshape(m,n)

	muestraimg( immean, 'Imagen media' )

	mode = V[0].reshape(m,n)
	
	muestraimg( mode, 'Imagen del primer modo de variacion' )

	a, vpmin, nu, porcentaje = errorCuadratico(S)

	plt.figure()
	plt.plot(porcentaje,'*')   
	plt.axis([0,conf.tambd,0,1])          
	
	immatrix = numpy.array(
			[numpy.array(Image.open(vfaces[i])).flatten() 
				for i in range(imnbr)],'f')

	V,S,immean1,EV = pca2.pca(immatrix, vpmin-1)
	
	pylab.figure()
	pylab.plot()
	pylab.title("Eigencaras")

	print V.shape
	for i in range(0,15):
		print '(m,n) =', m,n
		mode = V[i].reshape(m,n)
		pylab.subplot(3,5,i+1)
		pylab.gray()
		pylab.imshow(mode)

	print type(V)
	print V.shape

	
	fig = pylab.figure ()
	ax = p3.Axes3D (fig)
	x = V[0]
	y = V[1]
	z = V[2]
	
	print z.shape

	color = matplotlib.colors.Colormap("Greens", N=256) 
	c = matplotlib.cm.get_cmap(color)
	
	ax.scatter(x, y, z, zdir='z',s=10, cmap=c)
	ax.set_xlabel('X - Primer componente principal')
	ax.set_ylabel('Y - Segundo componente principal')
	ax.set_zlabel('Z - Tercer componente principal')

	fig.add_axes(ax)

	pylab.show()

	t_e = list()
	for k in conf.knn:
		clases = algKNN(V, entrena, V, k )
		t_e.append( arrayor( clases, prueba ) )
		
if __name__ == '__main__':
	main()
